package okw.network;

import java.io.IOException;
import java.util.ArrayList;

import okw.database.DatabaseManager;
import okw.database.Election;
import okw.database.Message;
import okw.gui.MainWindowO;

import core.messages.*;
import core.modules.database.corebase.ElectionData;
import core.modules.database.corebase.VotingCardCore;

/**
 * 
 * @author Maks
 * Watek odpowiedzialny za odbieranie wiadomosci od g�osuj�cych, wys�ania tego dalej do centrali
 * oraz wysylanie potwierdzenia klientowi
 * 
 */

public class ClientReceiver implements Runnable {

	ConnectionO cm = null;
	Queue2 queue2 = null;
	StanO stanO = null;
	Terminal terminal = null;
	
	public ClientReceiver(Terminal terminal, ConnectionO cm, Queue2 queue2, StanO stanO){

		this.cm = cm;
		this.terminal = terminal;
		this.queue2 = queue2;
		this.stanO = stanO;
	}
	
	//odbieranie glosu
	public void odebranoGlos(VoteMsg message) throws Exception{
		DatabaseManager db = DatabaseManager.getInstance();
		if(message != null && !db.hasMassage(terminal.getId(), message.getNumber())){
			if (message.getToken() != null){
				Info infoMsg = null;
				if(message.getVoteCore() != null){
					db = DatabaseManager.getInstance();
					if (db.saveVotes(message.getToken(), message.getVoteCore())) {
						infoMsg = new Info(stanO.getNr(), 6);
						System.out.println("dobry TOKEN!!");
					} else {
						infoMsg = new Info(stanO.getNr(), 7);
						System.out.println("ZLY TOKEN!!");
					}
				}
				cm.sendDown(terminal, infoMsg);
			}
			System.out.println("Komisja otrzymala od terminala GLOS: " + message.getNumber() + " : " + message.getMsg());
			
			Message VoteToDB = new Message(terminal.getId(), message.getNumber(), message.getElectionName());
			db.save(VoteToDB);
		} else {
			Info infoMsg = null;
			infoMsg = new Info(stanO.getNr(), 7);
			System.out.println("ZLY TOKEN!!");
			cm.sendDown(terminal, infoMsg);
		}
		Ack ack = new Ack(stanO.getNr(), message.getNumber());
		cm.sendDown(terminal, ack);
	}
	
	// odbieranie potwierdzenia
	public void odebranoPotwierdzenie(Ack ack){
		if(ack!=null){
			System.out.println("Otrzymano potwierdzenie od klienta dla nr:msg: " + ack.getNumber() + " " + ack.getReceived());
		} else{
			System.out.println("Nie otrzymano potwierdzenia!");
		}
	}
	
	// odbieranie informacji
	private void odebranoInformacje(Info info) throws Exception {
		if(info != null){
			System.out.println("Komisja otrzymala od klienta informacje nr:msg: " + info.getNumber() + " : " + info.getMsg());
		}
		switch(info.getMsg()){
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:{	 
			
			// prosba o dane do glosowania
			if(stanO.isKonfiguracja()){
				// wysylamy nulla, bo tryb konfiguracji
				Dane msg = new Dane(stanO.getNr(), null);
				cm.sendDown(terminal, msg);
			} else {
				// wysylamy dane bo normalne glosowanie
				DatabaseManager db = DatabaseManager.getInstance();
				System.out.println("ELENUM: " + MainWindowO.electionNr);
				ArrayList<VotingCardCore> votingCardCores = db
						.getVotingCardsToSend(db.get(Election.class,
								MainWindowO.electionNr));
				
				ElectionData electionData = new ElectionData();
				electionData.setVotingCards(votingCardCores);
	
				Dane msg = new Dane(stanO.getNr(), electionData);
				cm.sendDown(terminal, msg);
				
			}
			
			// wysylamy potwierdzenie
			Ack ack = new Ack(stanO.getNr(), info.getNumber());
			cm.sendDown(terminal, ack);
			
			break;
		}
		case 5:{ 
			
			// odebranie stanu terminala
			StanT stan = (StanT) info.getStan();
			System.out.println("ODEBRALEM STAN: " + stan);
			if(stan!=null)
				terminal.setStan(stan);
			
			//potwierdzenie
			Ack ack = new Ack(stanO.getNr(), info.getNumber());
			cm.sendDown(terminal, ack);
			
			break;
		}
		}

	}
	
	public void run() {
		try{	
			//odbiera wiadomosc
			while(true){ 
				// sprawdzamy typ wiadomosci
				Object message = terminal.getOis().readObject();
				if(message.getClass().equals(VoteMsg.class))
					odebranoGlos((VoteMsg)message);
				if(message.getClass().equals(Ack.class)){
					queue2.findToRemove((Ack)message);
					odebranoPotwierdzenie((Ack)message);
				}
				if(message.getClass().equals(Info.class))
					odebranoInformacje((Info)message);
			}

		} catch (Exception e){
			e.printStackTrace();
			e.getMessage();
			try {
				if(terminal.getSocket()!=null){
					terminal.getSocket().close();
					terminal.setSocket(null);
				}
				if(terminal.getOos()!=null){
					terminal.getOos().close();
					terminal.setOos(null);
				}
				if(terminal.getOis()!=null){
					terminal.getOis().close();
					terminal.setOis(null);
				}
				if(terminal.getStan()!=null)
					terminal.getStan().setPolaczenie(false);
				System.out.println("Zamykam polaczenie...");
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		System.out.println("Rozlaczono terminal");
		MainWindowO.aktualizujTerminale();
	}

}
